package com.pingao.mp.modular.sys.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pingao.mp.modular.sys.entity.Menu;
import com.pingao.mp.modular.sys.entity.Permission;
import com.pingao.mp.modular.sys.entity.Role;
import com.pingao.mp.modular.sys.entity.UserRoles;
import com.pingao.mp.modular.sys.mapper.MenuMapper;
import com.pingao.mp.modular.sys.mapper.PermissionMapper;
import com.pingao.mp.modular.sys.mapper.RoleMapper;
import com.pingao.mp.modular.sys.mapper.UserRolesMapper;
import com.pingao.mp.modular.sys.service.RoleService;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.jdbc.datasource.DataSourceTransactionManager;
import org.springframework.stereotype.Service;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;

import java.util.*;

@Service
public class RoleServiceImpl extends ServiceImpl<RoleMapper, Role> implements RoleService {
    @Autowired
    private PermissionMapper permissionMapper;
    @Autowired
    private MenuMapper menuMapper;
    @Autowired
    private UserRolesMapper userRolesMapper;
    @Autowired
    private DataSourceTransactionManager dataSourceTransactionManager;
    @Autowired
    private TransactionDefinition transactionDefinition;

    @Override
    public Map<String, Object> getRoleList(Integer pageNumber, Integer pageSize, String searchText, String sortName, String sortOrder) {
        Map<String, Object> map = new HashMap<>();
        Page<Role> page = new Page<>(pageNumber, pageSize);
        QueryWrapper<Role> wrapper = new QueryWrapper<>();
        wrapper.eq("1", "1");

        if (searchText != null && !"".equals(searchText)) {
            wrapper.and(q -> q.like(Role.COL_NAME, searchText).or().like(Role.COL_CODE, searchText).or().like(Role.COL_REPRESENT, searchText));
        }

        if (sortName.equals("createTime")) {
            sortName = Role.COL_CREATE_TIME;
        } else if (sortName.equals("updateTime")) {
            sortName = Role.COL_UPDATE_TIME;
        }

        if (sortOrder.equals("desc") || sortOrder.equals("DESC")) {
            wrapper.orderByDesc(sortName);
        } else {
            wrapper.orderByAsc(sortName);
        }
        page(page, wrapper);
        map.put("rows", page.getRecords());
        map.put("total", page.getTotal());
        return map;
    }

    @Override
    public void deleteRoleById(Long id) {
        //删除菜单
        //删除权限表中菜单的所有数据
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            permissionMapper.delete(new QueryWrapper<Permission>().eq(Permission.COL_ROLE_ID, id));
            userRolesMapper.delete(new QueryWrapper<UserRoles>().eq(UserRoles.COL_ROLE_ID, id));
            removeById(id);
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            if (transactionStatus != null) dataSourceTransactionManager.rollback(transactionStatus);
            throw e;
        }
    }

    @Override
    public List<Menu> getMenuList(Long id) {
        List<Menu> menus = menuMapper.selectList(new QueryWrapper<Menu>().isNull(Menu.COL_DELETE_TIME).orderByAsc(Menu.COL_SORT));
        List<Permission> permissions = permissionMapper.selectList(new QueryWrapper<Permission>().isNull(Permission.COL_DELETE_TIME).eq(Permission.COL_ROLE_ID, id));
        Set<Long> menuInPermissions = new HashSet<>();
        permissions.forEach(permission -> menuInPermissions.add(permission.getMenuId()));

        for (Menu menu : menus) {
            if (menuInPermissions.contains(menu.getId())) {
                //权限集合中有该菜单
                menu.setHasPermission(true);
            }
        }
        return menus;
    }

    @Override
    public void savePermissions(Long roleId, List<Long> menuIds) {
        TransactionStatus transactionStatus = null;
        try {
            transactionStatus = dataSourceTransactionManager.getTransaction(transactionDefinition);
            permissionMapper.delete(new QueryWrapper<Permission>().eq(Permission.COL_ROLE_ID, roleId));
            for (Long menuId : menuIds) {
                Permission permission = new Permission();
                permission.setRoleId(roleId);
                if (menuId == null || menuId < 1) {
                    continue;
                }
                permission.setMenuId(menuId);
                permissionMapper.insert(permission);
            }
            dataSourceTransactionManager.commit(transactionStatus);
        } catch (Exception e) {
            if (transactionStatus != null) dataSourceTransactionManager.rollback(transactionStatus);
            throw e;
        }
    }
}
